package com.sanley.piss.app.manager.shiro;

import cn.hutool.core.collection.CollectionUtil;
import com.gitee.dreamkaylee.shiro.authc.exception.ExpiredAccountException;
import com.gitee.dreamkaylee.shiro.authc.exception.NoneRoleException;
import com.gitee.dreamkaylee.shiro.authz.principal.ShiroPrincipal;
import com.gitee.dreamkaylee.shiro.authz.repository.AbstractShiroPrincipalRepository;
import com.gitee.dreamkaylee.shiro.constant.UserStatus;
import com.google.common.collect.Sets;
import com.sanley.piss.mapper.UserMapper;
import com.sanley.piss.model.po.Role;
import com.sanley.piss.model.vo.UserVO;
import org.apache.shiro.authc.*;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.stream.Collectors;

/**
 * @author limk
 * @date 2020/12/16 16:42
 */
@Component("sinopecRepository")
public class SinopecShiroPrincipalRepositoryImpl extends AbstractShiroPrincipalRepository {

    @Autowired
    private UserMapper userMapper;

    @Override
    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;

        if (!StringUtils.hasText(usernamePasswordToken.getUsername()) || usernamePasswordToken.getPassword() == null) {
            throw new UnknownAccountException("Username or password is required.");
        }

        UserVO user = userMapper.getUserByUsername(usernamePasswordToken.getUsername());
        if (user == null) {
            throw new UnknownAccountException("Username or password is incorrect, please re-enter.");
        }

        if (user.getState().equals(UserStatus.LOCKED.getCode())) {
            throw new LockedAccountException("Account is locked.");
        } else if (user.getState().equals(UserStatus.DISABLE.getCode())) {
            throw new DisabledAccountException("Account is disabled.");
        } else if (user.getState().equals(UserStatus.EXPIRED.getCode())) {
            throw new ExpiredAccountException("Account is expired.");
        }

        if (CollectionUtil.isEmpty(user.getRoles())) {
            throw new NoneRoleException("用户没有分配属角色");
        }

        ShiroPrincipal shiroPrincipal = new ShiroPrincipal();
        shiroPrincipal.setUserId(user.getId().toString());
        shiroPrincipal.setUsername(user.getUsername());
        shiroPrincipal.setPassword(user.getPassword());
        shiroPrincipal.setSalt(user.getSalt());
        shiroPrincipal.setOrganizations(Sets.newHashSet(String.valueOf(user.getDeptId())));
        shiroPrincipal.setRoles(user.getRoles().stream().map(Role::getCode).collect(Collectors.toSet()));
//        shiroPrincipal.setPerms(); // 权限，自己根据需求查
//        shiroPrincipal.setProfile(); // 其他用户信息，根据需求查
//        shiroPrincipal.setInitial(user.getInitial());

        return new SimpleAuthenticationInfo(shiroPrincipal, user.getPassword(),
                ByteSource.Util.bytes(shiroPrincipal.getSalt()), "login");

    }

    @Override
    public void doLock(Object principal) {
    }

}
